<template>
  <div class="notification-container">
    <div class="notification-header">
      <h1 class="page-title">游戏通知中心</h1>
      <div class="filter-tabs">
        <span
          v-for="(tab, idx) in tabs"
          :key="idx"
          :class="['filter-tab', { active: activeTab === tab.value }]"
          @click="activeTab = tab.value"
        >
          {{ tab.label }}
        </span>
      </div>
    </div>

    <div v-loading="loading" class="notification-content">
      <!-- 数据为空的提示 -->
      <el-empty v-if="!loading && filteredNotifications.length === 0" description="暂无通知" />

      <!-- 通知列表 -->
      <div v-else class="notification-list">
        <div
          v-for="notification in filteredNotifications"
          :key="notification.id"
          class="notification-item"
          :class="{ unread: !notification.read }"
          @click="openNotification(notification)"
        >
          <div class="notification-icon">
            <el-badge :is-dot="!notification.read">
              <el-icon :size="24">
                <component :is="getNotificationIcon(notification.type)" />
              </el-icon>
            </el-badge>
          </div>
          <div class="notification-content">
            <div class="notification-title">
              <span>{{ notification.title }}</span>
              <span class="notification-tag" :class="getTagClass(notification.type)">
                {{ getTypeName(notification.type) }}
              </span>
            </div>
            <div class="notification-summary">{{ notification.summary }}</div>
            <div class="notification-meta">
              <span class="notification-time">{{ formatTime(notification.time) }}</span>
              <span v-if="notification.read" class="notification-status">已读</span>
            </div>
          </div>
        </div>
      </div>

      <!-- 分页器 -->
      <div v-if="filteredNotifications.length > 0" class="pagination-container">
        <el-pagination
          v-model:current-page="currentPage"
          v-model:page-size="pageSize"
          :page-sizes="[10, 20, 30, 50]"
          background
          layout="total, sizes, prev, pager, next, jumper"
          :total="totalNotifications"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </div>

    <!-- 通知详情对话框 -->
    <el-dialog
      v-model="dialogVisible"
      :title="currentNotification?.title || '通知详情'"
      width="50%"
      destroy-on-close
    >
      <div v-if="currentNotification" class="notification-detail">
        <div class="notification-detail-header">
          <span class="notification-tag" :class="getTagClass(currentNotification.type)">
            {{ getTypeName(currentNotification.type) }}
          </span>
          <span class="notification-time">{{ formatTime(currentNotification.time) }}</span>
        </div>
        <div class="notification-content-html" v-html="currentNotification.content"></div>
        <div
          v-if="currentNotification.links && currentNotification.links.length > 0"
          class="notification-links"
        >
          <h4>相关链接：</h4>
          <div
            v-for="(link, index) in currentNotification.links"
            :key="index"
            class="notification-link"
          >
            <a :href="link.url" target="_blank">{{ link.title }}</a>
          </div>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, watch } from "vue";
import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";
import { Refresh, Star, Warning, Bell, Message } from "@element-plus/icons-vue";
import { ElMessage } from "element-plus";
import { 
  getNotifications, 
  getNotificationDetail, 
  markAsRead as markNotificationAsRead,
  type GameNotification,
  type NotificationType,
  type NotificationQuery
} from "@/api/game/inform";
import { useStomp } from "@/hooks/useStomp";

// 注册 dayjs 相对时间插件
dayjs.extend(relativeTime);

// 初始化WebSocket连接
const { subscribe, unsubscribe, connect, isConnected } = useStomp();
const notificationSubscriptionId = ref('');

// 标签页定义
interface TabItem {
  label: string;
  value: "all" | NotificationType | "unread";
}

// 标签页选项
const tabs = ref<TabItem[]>([
  { label: "全部", value: "all" },
  { label: "未读", value: "unread" },
  { label: "更新公告", value: "update" },
  { label: "活动通知", value: "event" },
  { label: "维护公告", value: "maintenance" },
  { label: "系统通知", value: "announcement" },
]);

// 当前选中的标签页
const activeTab = ref<"all" | NotificationType | "unread">("all");

// 通知数据
const notifications = ref<GameNotification[]>([]);
const loading = ref(false);
const dialogVisible = ref(false);
const currentNotification = ref<GameNotification | null>(null);

// 分页相关
const currentPage = ref(1);
const pageSize = ref(10);
const totalNotifications = ref(0);

// 根据标签筛选通知
const filteredNotifications = computed(() => {
  return notifications.value;
});

// 获取通知图标
const getNotificationIcon = (type: NotificationType): any => {
  switch (type) {
    case "update":
      return Refresh;
    case "event":
      return Star;
    case "maintenance":
      return Warning;
    case "announcement":
      return Bell;
    default:
      return Message;
  }
};

// 获取通知类型名称
const getTypeName = (type: NotificationType): string => {
  switch (type) {
    case "update":
      return "更新公告";
    case "event":
      return "活动通知";
    case "maintenance":
      return "维护公告";
    case "announcement":
      return "系统通知";
    default:
      return "通知";
  }
};

// 获取标签样式类
const getTagClass = (type: NotificationType): string => {
  switch (type) {
    case "update":
      return "tag-update";
    case "event":
      return "tag-event";
    case "maintenance":
      return "tag-maintenance";
    case "announcement":
      return "tag-announcement";
    default:
      return "";
  }
};

// 格式化时间
const formatTime = (time: string): string => {
  const now = dayjs();
  const notificationTime = dayjs(time);

  // 如果时间在24小时内，显示相对时间，否则显示具体日期
  if (now.diff(notificationTime, "hour") < 24) {
    return notificationTime.fromNow();
  } else {
    return notificationTime.format("YYYY-MM-DD HH:mm");
  }
};

// 获取通知数据
const fetchNotifications = async () => {
  loading.value = true;
  try {
    // 构建查询参数
    const params: NotificationQuery = {
      pageNum: currentPage.value,
      pageSize: pageSize.value
    };

    // 根据当前选中的标签页设置查询条件
    if (activeTab.value === 'unread') {
      params.read = false;
    } else if (activeTab.value !== 'all') {
      params.type = activeTab.value as NotificationType;
    }

    // 调用API获取数据
    const res = await getNotifications(params);
    console.log('API返回数据:', res);
    
    if (res) {
      // 设置通知数据和总数
      notifications.value = res.list || [];
      totalNotifications.value = res.total || 0;
    } else {
      ElMessage.error("获取通知列表失败: 无效的响应数据");
      notifications.value = [];
      totalNotifications.value = 0;
    }
  } catch (error) {
    ElMessage.error("获取通知列表失败");
    console.error("获取通知列表失败:", error);
    notifications.value = [];
    totalNotifications.value = 0;
  } finally {
    loading.value = false;
  }
};

// 打开通知详情
const openNotification = async (notification: GameNotification) => {
  try {
    loading.value = true;
    // 获取通知详情
    const notificationDetail = await getNotificationDetail(notification.id);
    console.log('通知详情数据:', notificationDetail);

    if (notificationDetail) {
      currentNotification.value = notificationDetail;
      dialogVisible.value = true;

      // 如果通知未读，则标记为已读
      if (!notification.read) {
        await markAsRead(notification.id);
      }
    } else {
      ElMessage.error("获取通知详情失败: 无效的响应数据");
    }
  } catch (error) {
    ElMessage.error("获取通知详情失败");
    console.error("获取通知详情失败:", error);
  } finally {
    loading.value = false;
  }
};

// 标记通知为已读
const markAsRead = async (id: number) => {
  try {
    await markNotificationAsRead(id);
    // 更新本地通知状态
    const index = notifications.value.findIndex((item) => item.id === id);
    if (index !== -1) {
      notifications.value[index].read = true;
    }
    // 重新获取通知列表以更新状态
    fetchNotifications();
  } catch (error) {
    ElMessage.error("标记已读失败");
    console.error("标记已读失败:", error);
  }
};

// 处理页大小变化
const handleSizeChange = (size: number) => {
  pageSize.value = size;
  currentPage.value = 1; // 重置为第一页
  fetchNotifications();
};

// 处理页码变化
const handleCurrentChange = (page: number) => {
  currentPage.value = page;
  fetchNotifications();
};

// 处理收到实时通知
const handleNewNotification = (message: any) => {
  try {
    const notification = JSON.parse(message.body);
    console.log('收到新通知:', notification);
    
    // 显示通知提示
    ElMessage({
      type: 'success',
      message: `收到新通知: ${notification.title}`,
      duration: 5000
    });
    
    // 刷新通知列表
    fetchNotifications();
  } catch (error) {
    console.error('处理通知消息出错:', error);
  }
};

// 初始化WebSocket订阅
const initWebSocketSubscription = () => {
  try {
    if (isConnected.value) {
      // 订阅通知主题
      notificationSubscriptionId.value = subscribe('/topic/notifications', handleNewNotification);
      console.log('已订阅通知主题, ID:', notificationSubscriptionId.value);
    } else {
      // 如果未连接，先连接再订阅
      connect();
      console.log('WebSocket未连接，正在尝试连接...');
      // 延迟一秒后再次尝试订阅，给连接一些时间
      setTimeout(() => {
        if (isConnected.value && !notificationSubscriptionId.value) {
          notificationSubscriptionId.value = subscribe('/topic/notifications', handleNewNotification);
          console.log('延迟订阅通知主题成功, ID:', notificationSubscriptionId.value);
        }
      }, 1000);
    }
  } catch (error) {
    console.error('WebSocket订阅失败:', error);
  }
};

// 监听连接状态
watch(isConnected, (connected) => {
  if (connected && !notificationSubscriptionId.value) {
    // 连接成功后订阅
    notificationSubscriptionId.value = subscribe('/topic/notifications', handleNewNotification);
    console.log('已订阅通知主题, ID:', notificationSubscriptionId.value);
  }
});

// 监听标签变化，重新加载数据
watch(activeTab, () => {
  currentPage.value = 1; // 切换标签时，重置为第一页
  fetchNotifications();
});

// 组件挂载时加载数据并连接WebSocket
onMounted(() => {
  fetchNotifications();
  initWebSocketSubscription();
});

// 组件卸载时取消订阅
onUnmounted(() => {
  if (notificationSubscriptionId.value) {
    unsubscribe(notificationSubscriptionId.value);
    console.log('已取消订阅通知主题');
  }
});
</script>

<style scoped>
.notification-container {
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
  background-color: #f8f9fa;
}

.notification-header {
  margin-bottom: 30px;
}

.page-title {
  margin: 0 0 20px 0;
  font-size: 32px;
  font-weight: 700;
  color: #333;
}

.filter-tabs {
  display: flex;
  gap: 16px;
  margin-bottom: 20px;
  border-bottom: 1px solid #eaeaea;
  padding-bottom: 10px;
  flex-wrap: wrap;
}

.filter-tab {
  padding: 8px 16px;
  cursor: pointer;
  font-size: 15px;
  border-radius: 20px;
  transition: all 0.3s ease;
  color: #666;
}

.filter-tab:hover {
  background-color: #f1f1f1;
  color: #333;
}

.filter-tab.active {
  background-color: #333;
  color: white;
  font-weight: 500;
}

.notification-list {
  background-color: white;
  border-radius: 12px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
  overflow: hidden;
  margin-bottom: 20px;
}

.notification-item {
  display: flex;
  padding: 20px;
  border-bottom: 1px solid #ebeef5;
  transition: all 0.3s ease;
  cursor: pointer;
}

.notification-item:last-child {
  border-bottom: none;
}

.notification-item:hover {
  background-color: #f9fafc;
}

.notification-item.unread {
  background-color: #f0f9ff;
}

.notification-item.unread:hover {
  background-color: #ecf5ff;
}

.notification-icon {
  margin-right: 16px;
  font-size: 24px;
  color: #409eff;
  display: flex;
  align-items: flex-start;
}

.notification-content {
  flex: 1;
}

.notification-title {
  font-size: 16px;
  font-weight: 600;
  margin-bottom: 8px;
  color: #303133;
  display: flex;
  align-items: center;
  gap: 10px;
}

.notification-tag {
  font-size: 12px;
  padding: 2px 6px;
  border-radius: 4px;
  font-weight: normal;
}

.tag-update {
  background-color: #e1f3d8;
  color: #67c23a;
}

.tag-event {
  background-color: #fdf6ec;
  color: #e6a23c;
}

.tag-maintenance {
  background-color: #fef0f0;
  color: #f56c6c;
}

.tag-announcement {
  background-color: #f0f9ff;
  color: #409eff;
}

.notification-summary {
  font-size: 14px;
  color: #606266;
  margin-bottom: 8px;
  line-height: 1.5;
}

.notification-meta {
  font-size: 12px;
  color: #909399;
  display: flex;
  justify-content: space-between;
}

.notification-time {
  color: #909399;
}

.notification-status {
  color: #67c23a;
}

.pagination-container {
  text-align: center;
  margin-top: 30px;
}

/* 通知详情样式 */
.notification-detail {
  padding: 0 20px;
}

.notification-detail-header {
  display: flex;
  justify-content: space-between;
  margin-bottom: 20px;
  padding-bottom: 15px;
  border-bottom: 1px solid #ebeef5;
}

.notification-content-html {
  line-height: 1.8;
  color: #303133;
}

.notification-content-html h3 {
  margin-top: 0;
  margin-bottom: 20px;
  color: #303133;
}

.notification-content-html p {
  margin-bottom: 16px;
}

.notification-content-html ul,
.notification-content-html ol {
  padding-left: 20px;
  margin-bottom: 16px;
}

.notification-content-html li {
  margin-bottom: 8px;
}

.notification-links {
  margin-top: 20px;
  padding-top: 15px;
  border-top: 1px solid #ebeef5;
}

.notification-links h4 {
  margin-top: 0;
  margin-bottom: 10px;
  font-size: 16px;
  color: #303133;
}

.notification-link {
  margin-bottom: 5px;
}

.notification-link a {
  color: #409eff;
  text-decoration: none;
}

.notification-link a:hover {
  text-decoration: underline;
}
</style>
